﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CPF_experement
{
    class AgentState : IComparable<AgentState>
    {
        public int pos_X;
        public int pos_Y;
        public int huristic;
        public Agent agent;
        public int arrivalTime;
        public int currentStep;
        public int direction;
        public AgentState prev;

        public AgentState(int pos_X, int pos_Y, Agent agent)
        {
            this.pos_X=pos_X;
            this.pos_Y=pos_Y;
            direction = 0;
            this.agent=agent;
            setHuristic(0);
        }

        public AgentState(AgentState copy)
        {
            this.pos_X = copy.pos_X;
            this.pos_Y = copy.pos_Y;
            this.agent = copy.agent;
            this.huristic = copy.huristic;
            this.arrivalTime = copy.arrivalTime;
            this.direction = copy.direction;
        }

        public void setHuristic(int step)
        {
            huristic = True_Path_Huristic.getHuristic(agent.agentNum, pos_X, pos_Y);
            if (huristic == 0)
                arrivalTime = step;
        }

#region moves

        public void move(int direction, int step)
        {
            switch (direction)
            {
                case 0:             //move left
                    pos_X--;
                    setHuristic(step);
                    break;
                case 1:             //move up
                    pos_Y++;
                    setHuristic(step);
                    break;
                case 2:             //move right
                    pos_X++;
                    setHuristic(step);
                    break;
                case 3:             //move down
                    pos_Y--;
                    setHuristic(step);
                    break;
                case 4:             //move left+Up
                    pos_X--;
                    pos_Y++;
                    setHuristic(step);
                    break;
                case 5:             //move right+up
                    pos_X++;
                    pos_Y++;
                    setHuristic(step);
                    break;
                case 6:             //move right+down
                    pos_X++;
                    pos_Y--;
                    setHuristic(step);
                    break;
                case 7:             //move left+down
                    pos_X--;
                    pos_Y--; 
                    setHuristic(step);
                    break;
            }
        }
#endregion
        public override bool Equals(object obj)
        {
            AgentState that = (AgentState)obj;
            if (this.pos_X==that.pos_X && this.pos_Y==that.pos_Y && this.agent==that.agent && this.currentStep==that.currentStep &&(!Run.trevor_A_Star || this.direction==that.direction))
            {
                return true;
            }
            return false;
        }
        public override int GetHashCode()
        {
            return (1 + this.agent.agentNum) * (1 + this.pos_X) * (1 + this.pos_Y) * (1 + this.currentStep);
        }

        public int CompareTo(AgentState that)
        {
            if (this.huristic + this.currentStep < that.huristic + that.currentStep)
                return -1;
            if (this.huristic + this.currentStep > that.huristic + that.currentStep)
                return 1;
            if (this.currentStep < that.currentStep)
                return -1;
            if (this.currentStep > that.currentStep)
                return 1;
            return 0;
        }
        public override string ToString()
        {
            return " step-"+currentStep+" possison ("+pos_X+","+pos_Y+")";
        }
    }
}
